package com.sparrow.common.ai.behaviortree.node.impl;

import com.google.common.base.Preconditions;
import com.sparrow.common.ai.behaviortree.node.AbstractBehaviorNode;
import com.sparrow.common.ai.behaviortree.node.BehaviorNode;
import com.sparrow.common.ai.behaviortree.task.BehaviorTask;
import com.sparrow.common.ai.behaviortree.task.impl.ConditionDecorateTask;
import com.sparrow.common.ai.behaviortree.task.impl.ConditionTask;
import java.util.ArrayList;
import java.util.List;

/**
 * 条件修饰节点
 */
public class ConditionDecorateNode extends AbstractBehaviorNode {

    private final List<ConditionNode> conditionNodes = new ArrayList<>();
    private final BehaviorNode targetNode;  // 被修饰的目标节点（Action 或复合节点）
    private final List<BehaviorNode> childs;

    private boolean value;

    public ConditionDecorateNode(List<BehaviorNode> childs, boolean value) {
        this.value = value;
        BehaviorNode tmpTarget = null;
        for (BehaviorNode child : childs) {
            if (child instanceof ConditionNode) {
                conditionNodes.add((ConditionNode) child);
            } else if (child instanceof ActionNode
                    || child instanceof SelectorNode
                    || child instanceof SequenceNode
                    || child instanceof ParallelNode) {
                if (tmpTarget != null) {
                    throw new IllegalArgumentException(
                            "ConditionDecorate 只能修饰一个目标节点"
                    );
                }
                tmpTarget = child;
            }
        }

        Preconditions.checkNotNull(tmpTarget, "ConditionDecorate 必须有一个目标节点");
        this.targetNode = tmpTarget;
        this.childs = childs;
    }

    @Override
    public BehaviorTask createTask() {
        List<ConditionTask> conditionTasks = new ArrayList<>();
        for (ConditionNode c : conditionNodes) {
            conditionTasks.add((ConditionTask) c.createTask());
        }
        return new ConditionDecorateTask(conditionTasks, targetNode.createTask(), value);
    }

    @Override
    public List<BehaviorNode> getChildren() {
        return childs;
    }
}
